/**
 * 
 */
package de.htwg.ppt2html5.export;


import java.io.File;
import java.util.List;

import org.docx4j.dml.BaseStyles;
import org.docx4j.dml.BaseStyles.FontScheme;
import org.docx4j.dml.CTColor;
import org.docx4j.dml.CTColorScheme;
import org.docx4j.dml.CTGradientStop;
import org.docx4j.dml.CTSchemeColor;
import org.docx4j.dml.CTStyleMatrix;
import org.docx4j.dml.CTTextCharacterProperties;
import org.docx4j.dml.CTTextParagraphProperties;
import org.docx4j.dml.CTTransform2D;
import org.docx4j.dml.STTextCapsType;
import org.docx4j.openpackaging.parts.PresentationML.SlideLayoutPart;
import org.pptx4j.pml.CTPlaceholder;
import org.pptx4j.pml.STPlaceholderType;
import org.pptx4j.pml.Shape;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.htwg.ppt2html5.extraction.Presentation;
import de.htwg.ppt2html5.extraction.Slide;


/**
 * this class builds the CSS file for the HTML
 * 
 * @author Roman Allenov
 */
public class CSSBuilder {

   private static Logger log = LoggerFactory.getLogger(CSSBuilder.class);

   private String        css = "";


   /**
    * this method builds the CSS with given information from presentation and its slides
    * 
    * @param presentation
    * @param slideList
    * @param parentPath
    * @return the CSS
    */
   public String buildCSS(Presentation presentation, List<Slide> slideList, File file)
   {
      // change slashes for reveal.js to be able to read CSS properly: it reads normal slashes
      String path = file.getParent().replace('\\', '/');
      String fileName = file.getName();

      // needed vars
      Shape ctrTitleShape = null;
      Shape subTitleShape = null;
      Shape slideTitleShape = null;
      Shape randomShape = null;
      Shape slideBodyShape = null;
      /**
       * POSITIONS of shapes
       */
      CTTransform2D posCtrTitle = null;
      CTTransform2D posCtrSubTitle = null;
      CTTransform2D posSlideTitle = null;
      CTTransform2D posSlideBody = null;
      CTTransform2D posRandomShape = null;

      String posSlideTitle_str = "";
      String posRandomShape_str = "";

      // slides are sorted, so title slide should be the first
      SlideLayoutPart titleSlideLayout = slideList.get(0).getSlideLayout();

      // TODO size from CTTransform2D is needed for html builder, for div sizes
      // TODO position of the div beginning needed here in css

      // TITLE SLIDE
      // .getContents() is same as .getJaxbElement()
      List<Object> titleSldShapes = titleSlideLayout.getContents().getCSld().getSpTree().getSpOrGrpSpOrGraphicFrame();
      for (Object object : titleSldShapes) {
         if (object instanceof Shape) {
            Shape sp = (Shape)object;
            CTPlaceholder ph = sp.getNvSpPr().getNvPr().getPh();
            if (ph != null && ph.getType().value().equals(STPlaceholderType.CTR_TITLE.value())) {
               ctrTitleShape = sp;
               posCtrTitle = sp.getSpPr().getXfrm();
            }
            else if (ph != null
                     && ph.getType().value().equals(STPlaceholderType.SUB_TITLE.value())) {
               subTitleShape = sp;
               posCtrSubTitle = sp.getSpPr().getXfrm();
            }
         }
      }

      // go on with following slides
      for (int i = 1; i < slideList.size(); i++) {
         SlideLayoutPart slideLayout = slideList.get(i).getSlideLayout();
         List<Object> slideShapes = slideLayout.getContents().getCSld().getSpTree().getSpOrGrpSpOrGraphicFrame();
         for (Object object : slideShapes) {
            if (object instanceof Shape) {
               Shape sp = (Shape)object;
               if (sp.getNvSpPr().getNvPr() != null && sp.getNvSpPr().getNvPr().getPh() != null) {
                  CTPlaceholder shapePh = sp.getNvSpPr().getNvPr().getPh();
                  // check if it's a title
                  if (shapePh.getType() != null
                      && shapePh.getType().value().equals(STPlaceholderType.TITLE.value())) {
                     slideTitleShape = sp;
                     if (sp.getSpPr() != null && sp.getSpPr().getXfrm() != null) {
                        posSlideTitle = sp.getSpPr().getXfrm();
                     }
                     else {
                        posSlideTitle_str = "top";
                     }
                  }
                  // else it's another shape
                  else {
                     randomShape = sp;
                     if (sp.getSpPr() != null && sp.getSpPr().getXfrm() != null) {
                        posRandomShape = sp.getSpPr().getXfrm();
                     }
                     else {
                        posRandomShape_str = "center";
                     }
                  }
               }
            }
         }
      }

      /**
       * PROPERTIES OF TEXT SHAPES
       */
      CTTextCharacterProperties ctrTitleTextProps = ctrTitleShape.getTxBody().getLstStyle().getLvl1PPr().getDefRPr();
      List<CTGradientStop> ctrGS = ctrTitleTextProps.getGradFill().getGsLst().getGs();
      CTSchemeColor ctrSchemeColor = null;
      if (ctrGS.get(0).getSchemeClr() != null) {
         ctrSchemeColor = ctrGS.get(0).getSchemeClr();
      }
      String schemeAccent = "";
      if (ctrSchemeColor != null) {
         schemeAccent = ctrSchemeColor.getVal().value();
      }
      CTTextParagraphProperties subTitleTextProps = subTitleShape.getTxBody().getLstStyle().getLvl1PPr();

      int sizeCtrTitle = ctrTitleTextProps.getSz() / 100;
      String alignSubTitle = subTitleTextProps.getAlgn().value();
      if (alignSubTitle.equals("ctr")) {
         alignSubTitle = "center";
      }
      String uppercase = "";
      if (ctrTitleTextProps.getCap().value().equals(STTextCapsType.ALL.value())) {
         uppercase = "uppercase";
      }

      /**
       * FONTS & COLORS OF FONTS
       */

      FontScheme font = presentation.getFont();
      BaseStyles presStyles = presentation.getThemes().get(0).getContents().getThemeElements();
      CTColorScheme colorScheme = presStyles.getClrScheme();
      CTColor color = colorScheme.getAccent1();
      StringBuilder sb = new StringBuilder();
      String colorTitle = "";
      if (!schemeAccent.isEmpty() && schemeAccent.equals("accent1")) {
         byte[] byteArray = color.getSrgbClr().getVal();
         for (int i = 0; i < byteArray.length; i++) {
            sb.append(String.format("%02X ", byteArray[i]));

            colorTitle += String.format("%02X", byteArray[i]);

         }
      }
      CTStyleMatrix style = presStyles.getFmtScheme();

      /***************************************************************************/
      //@formatter:off
      setCss(getCss() + (//"@import "
          //+  "url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);"
//            /**
//             * Default theme for reveal.js.
//             *
//             * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
//             */
//            @font-face {
//               font-family: 'League Gothic';
//               src: url("../../lib/font/league_gothic-webfont.eot");
//               src: url("../../lib/font/league_gothic-webfont.eot?#iefix")
//                  format("embedded-opentype"),
//                  url("../../lib/font/league_gothic-webfont.woff") format("woff"),
//                  url("../../lib/font/league_gothic-webfont.ttf") format("truetype"),
//                  url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular")
//                  format("svg");
//               font-weight: normal;
//               font-style: normal;
//            }
            
              "\n/*********************************************"
            + "\n* GLOBAL STYLES"
            + "\n*********************************************/"
            + "\nbody {"
            +  "\nfont-family: \"" + font.getMinorFont().getLatin().getTypeface() + "\";"
            +  "\nbackground-image: url(\"" + path + "/background-" + fileName.substring(0, file.getName().indexOf(".")) + ".jpeg\");"
            +  "\nbackground-position: center;"
            +  "\nbackground-size: cover;"
            +  "\nbackground-repeat: no-repeat;"
            +  "\n}"
            
//            .reveal {
//               font-family: "Lato", sans-serif;
//               font-size: 36px;
//               font-weight: normal;
//               letter-spacing: -0.02em;
//               color: #eeeeee;
//            }
            
           +  "\n::selection {"
           +  "\ncolor: white;"
           +  "\nbackground: grey;"
           +  "\ntext-shadow: none;"
           +  "\n}"
            
         +  "\n/*********************************************"
         +  "\n* HEADERS"
         +  "\n*********************************************/"
         +  "\n.reveal h1,.reveal h2,.reveal h3,.reveal h4,.reveal h5,.reveal h6 {"
//         +  "\nmargin: 0 0 20px 0;"
          +  "\ncolor: #" + colorTitle + ";"
          +  "\nfont-family: \"" + font.getMajorFont().getLatin().getTypeface() + "\";"
//          +  "\nline-height: 0.9em;"
//          +  "\nletter-spacing: 0.02em;"
          +  "\nfont-size: " + sizeCtrTitle + "px;"
          +  "\ntext-transform: " + uppercase +";"
          +  "\ntext-shadow: " + /*0px 0px 6px rgba(0, 0, 0, 0.2)*/";"
          +  "\n}"
            
          
          +  "\n#" + STPlaceholderType.CTR_TITLE.value() + " {"
          +  "\ncolor: #" + colorTitle + ";"
          +  "\nfont-size: " + sizeCtrTitle + "px;"
          +  "\nposition: " + /*posCtrTitle != null ? posCtrTitle.getOff().getX() : */"center" + ";"
          + "\n}"

          +  "\n#" + STPlaceholderType.SUB_TITLE.value() + " {"
          +  "\nfont-size: " + (sizeCtrTitle - 5) + "px;"
          +  "\nposition: " + alignSubTitle + ";"
          +  "\n}"

          +  "\n.reveal h1 " + STPlaceholderType.TITLE.value() + " {"
          +  "\nfont-size: " + sizeCtrTitle + "px;"
          +  "\nposition: " + /*posSlideTitle != null ?  
          new Point((int)posSlideTitle.getOff().getX() / 12700, (int)posSlideTitle.getOff().getY()/12700) "center" : */
          posSlideTitle_str + ";"
          +  "\n}"
            
            /*********************************************
             * LINKS
             *********************************************/
//            .reveal a:not (.image ) {
//               color: #13daec;
//               text-decoration: none;
//               -webkit-transition: color .15s ease;
//               -moz-transition: color .15s ease;
//               -ms-transition: color .15s ease;
//               -o-transition: color .15s ease;
//               transition: color .15s ease;
//            }
//            
//            .reveal a:not (.image ):hover {
//               color: #71e9f4;
//               text-shadow: none;
//               border: none;
//            }
            
//            .reveal .roll span:after {
//               color: #fff;
//               background: #0d99a5;
//            }
            
            /*********************************************
             * IMAGES
             *********************************************/
//            .reveal section img {
//               margin: 15px 0px;
//               background: rgba(255, 255, 255, 0.12);
//               border: 4px solid #eeeeee;
//               box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
//               -webkit-transition: all .2s linear;
//               -moz-transition: all .2s linear;
//               -ms-transition: all .2s linear;
//               -o-transition: all .2s linear;
//               transition: all .2s linear;
//            }
//            
//            .reveal a:hover img {
//               background: rgba(255, 255, 255, 0.2);
//               border-color: #13daec;
//               box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
//            }
            
            /*********************************************
             * NAVIGATION CONTROLS
             *********************************************/
           +  "\n.reveal .controls div.navigate-left,.reveal .controls div.navigate-left.enabled {"
           +  "\nborder-right-color: #13daec;}"
            
            + "\n.reveal .controls div.navigate-right,.reveal .controls div.navigate-right.enabled {"
            + "\nborder-left-color: #13daec;}"
            
            + "\n.reveal .controls div.navigate-up,.reveal .controls div.navigate-up.enabled {"
            + "\nborder-bottom-color: #13daec;}"
            
            + "\n.reveal .controls div.navigate-down,.reveal .controls div.navigate-down.enabled {"
            + "\nborder-top-color: #13daec; }"
            
            + "\n.reveal .controls div.navigate-left.enabled:hover {"
            + "\nborder-right-color: #71e9f4; }"
            
            + "\n.reveal .controls div.navigate-right.enabled:hover {"
            + "\nborder-left-color: #71e9f4;}"
            
            + "\n.reveal .controls div.navigate-up.enabled:hover {"
            + "\nborder-bottom-color: #71e9f4;}"
            
            + "\n.reveal .controls div.navigate-down.enabled:hover {"
            + "\nborder-top-color: #71e9f4;}"
            
            /*********************************************
             * PROGRESS BAR
             *********************************************/
              + "\n.reveal .progress {"
              + "\nbackground: rgba(0, 0, 0, 0.2);}"
            
              + "\n.reveal .progress span {"
              + "\nbackground: #13daec;"
              + "\n-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);"
              + "\n-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);"
              + "\n-ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);"
              + "\n-o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);"
              + "\ntransition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);}"
            
            /*********************************************
             * SLIDE NUMBER
             *********************************************/
              + "\n.reveal .slide-number {"
              + "\ncolor: #13daec;"
              + "}"));
      //@formatter:on
      return getCss();
   }


   public String getCss()
   {
      return css;
   }


   public void setCss(String css)
   {
      this.css = css;
   }
}
